Import Dataset and create working dataset:

#install.packages("plotly")
library(plotly)
library(reshape2)
library(tidyverse)
games <- read.csv("../../data/vgsales.csv")
game_melt <- melt(data=games,id.vars = c("Rank","Name","Platform","Year","Genre","Publisher"),measure.vars=c("NA_Sales","EU_Sales","JP_Sales","Other_Sales","Global_Sales"))
game_melt$Year <- as.integer(game_melt$Year)
NAs introduced by coercion
colnames(game_melt)[7] <- "Region"
colnames(game_melt)[8] <- "Copies Sold"
head(game_melt)
seq(1970,2017,step=5)
In seq.default(1970, 2017, step = 5) :
 extra argument 㤼㸱step㤼㸲 will be disregarded
 [1] 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982
[14] 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995
[27] 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008
[40] 2009 2010 2011 2012 2013 2014 2015 2016 2017

Graph time baby!

#Number of Copies Sold
graph1 <- game_melt %>% 
    filter(Region == "NA_Sales") %>%
    group_by(Region,Year,Genre) %>%
    summarise("Copies Sold" = sum(`Copies Sold`)) %>% 
    ggplot() +
    aes(x=Year,
        y=`Copies Sold`,
        fill = Genre) + 
    geom_bar(stat="identity")+
    theme(axis.text.x = element_text(angle = 90, hjust=0.95, vjust=0.2)) +
    ylab("Number of Copies Sold (in millions)")
`summarise()` regrouping output by 'Region', 'Year' (override with `.groups` argument)
    
ggplotly(graph1)
Removed 12 rows containing missing values (position_stack).
#Number Releases
graph2 <- game_melt %>% 
    filter(Region == "NA_Sales") %>%
    group_by(Region,Year,Genre) %>%
    count(Year,Genre) %>%
    rename(`Number of Releases`="n")%>% 
    ggplot() +
    aes(x=Year,
        y=`Number of Releases`,
        fill = Genre) + 
    geom_bar(stat="identity")+
    theme(axis.text.x = element_text(angle = 90, hjust=0.95, vjust=0.2))+
    ylab("Number of Games Released")
ggplotly(graph2)
```r
#Number of Platforms, Genres and Publishers with games > 100 copies sold 
graph3 <- game_melt %>% 
    filter(Region == \JP_Sales\) %>%
    group_by(Year)%>%
    melt(id.vars=c(\Year\),measure.vars=c(\Genre\,\Platform\,\Publisher\)) %>%
    rename(Category='variable') %>% 
    group_by(Year,Category) %>%
    unique() %>%
    count(Year,Category) %>%
    rename(`Counts of Genres, Publishers and Platforms`= n) %>% 
    ggplot() +
    aes(x=Year,
        y=`Counts of Genres, Publishers and Platforms`,
        fill = Category) + 
    geom_bar(stat=\identity\)+
    theme(axis.text.x = element_text(angle = 90, hjust=0.95, vjust=0.2))+
    ylab(\Counts of Genres
testfxc <-function(reg,plat,gen,pub,years) {
         # Input: List of Regions, Platforms, Genres, Publishers, Min and Max Year
         # Output: Graph
         #
         # Create subset based on filters 
         # Pass to graph
         # Output graph

        filter_region = reg
        
         if (plat != "all"){
             filter_plat = plat
         } else {
             filter_plat = unique(game_melt$Platform)
         }
         if (gen != "all"){
             filter_gen = gen
         } else {
             filter_gen = unique(game_melt$Genre)
         }
         if (pub != "all"){
             filter_pub = pub
         } else {
             filter_pub = unique(game_melt$Publisher)
         }
         min_year = years[1]
         max_year = years[2]
         
         graph1 <- game_melt[,2:8] %>% 
             subset(Region %in% filter_region, Platform %in% filter_plat, Genre %in% filter_gen, Publisher %in% filter_pub, Year >= min_year | Year <= max_year) %>%
             group_by(Region,Year,Genre) %>%
             summarise("Copies Sold" = sum(`Copies Sold`)) %>% 
             ggplot() +
             aes(x=Year,
                 y=`Copies Sold`,
                 fill = Genre) + 
             geom_bar(stat="identity")+
             theme(axis.text.x = element_text(angle = 90, hjust=0.95, vjust=0.2)) +
             ylab("Number of Copies Sold (in millions)")
         ggplotly(graph1)
    }
filter_region = list("JP_Sales")
filter_plat = unique(game_melt$Platform)

filter_gen = unique(game_melt$Genre)

filter_pub = unique(game_melt$Publisher)

min_year = 1980
max_year = 2017
 graph1 <- game_melt %>% 
     subset(Region %in% filter_region & Platform %in% filter_plat & Genre %in% filter_gen & Publisher %in% filter_pub & Year >= min_year & Year <= max_year) %>%
     group_by(Year,Genre) %>%
     summarise("Copies Sold" = sum(`Copies Sold`)) %>% 
     ggplot() +
     aes(x=Year,
         y=`Copies Sold`,
         fill = Genre) + 
     geom_bar(stat="identity")+
     theme(axis.text.x = element_text(angle = 90, hjust=0.95, vjust=0.2)) +
     ylab("Number of Copies Sold (in millions)")
`summarise()` regrouping output by 'Year' (override with `.groups` argument)
 ggplotly(graph1)

}
Error: unexpected '}' in "}"
game_melt$Year > 2000
   [1]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE
  [25]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
  [49]  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE
  [73]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
  [97] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
 [121]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
 [145]  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
 [169]  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE    NA  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE
 [193]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE
 [217]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
 [241]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
 [265]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE
 [289]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [313] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE
 [337]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
 [361]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE    NA  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [385]  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [409]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE    NA
 [433]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE
 [457]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE    NA  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [481]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
 [505] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
 [529]  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE
 [553]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE
 [577] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [601]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE    NA  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
 [625]    NA  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE FALSE
 [649] FALSE    NA  TRUE  TRUE    NA FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
 [673] FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE
 [697]  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE    NA  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE
 [721]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
 [745] FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE  TRUE
 [769]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE    NA  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
 [793]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [817]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE
 [841]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [865] FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
 [889] FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [913]  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE
 [937]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
 [961]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE
 [985] FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
 [ reached getOption("max.print") -- omitted 81985 entries ]
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KSW1wb3J0IERhdGFzZXQgYW5kIGNyZWF0ZSB3b3JraW5nIGRhdGFzZXQ6DQpgYGB7cn0NCiNpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHJlc2hhcGUyKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpnYW1lcyA8LSByZWFkLmNzdigiLi4vLi4vZGF0YS92Z3NhbGVzLmNzdiIpDQpnYW1lX21lbHQgPC0gbWVsdChkYXRhPWdhbWVzLGlkLnZhcnMgPSBjKCJSYW5rIiwiTmFtZSIsIlBsYXRmb3JtIiwiWWVhciIsIkdlbnJlIiwiUHVibGlzaGVyIiksbWVhc3VyZS52YXJzPWMoIk5BX1NhbGVzIiwiRVVfU2FsZXMiLCJKUF9TYWxlcyIsIk90aGVyX1NhbGVzIiwiR2xvYmFsX1NhbGVzIikpDQpnYW1lX21lbHQkWWVhciA8LSBhcy5pbnRlZ2VyKGdhbWVfbWVsdCRZZWFyKQ0KY29sbmFtZXMoZ2FtZV9tZWx0KVs3XSA8LSAiUmVnaW9uIg0KY29sbmFtZXMoZ2FtZV9tZWx0KVs4XSA8LSAiQ29waWVzIFNvbGQiDQpoZWFkKGdhbWVfbWVsdCkNCmBgYA0KDQpgYGB7cn0NCnBsYXRmb3JtX2ZpbHRlciA8LSB1bmlxdWUoZ2FtZXMkUGxhdGZvcm0pICU+JQ0KICAgIHB1cnJyOjptYXAoZnVuY3Rpb24oY29sKSBsaXN0KGxhYmVsID0gY29sLCB2YWx1ZSA9IGNvbCkpDQpwbGF0Zm9ybV9maWx0ZXIgPC0gYXBwZW5kKHBsYXRmb3JtX2ZpbHRlcixsaXN0KGxpc3QobGFiZWw9IkFsbCIsdmFsdWU9dW5pcXVlKGdhbWVzJFBsYXRmb3JtKSkpKQ0KYGBgDQpgYGB7cn0NCmdhbWVfbWVsdCAlPiUNCiAgICBzdWJzZXQoUmVnaW9uICVpbiUgIk5BX1NhbGVzIikNCmdhbWVfbWVsdFssMjo4XQ0KYGBgDQoNCkdyYXBoIHRpbWUgYmFieSENCmBgYHtyfQ0KI051bWJlciBvZiBDb3BpZXMgU29sZA0KZ3JhcGgxIDwtIGdhbWVfbWVsdCAlPiUgDQogICAgZmlsdGVyKFJlZ2lvbiA9PSAiTkFfU2FsZXMiKSAlPiUNCiAgICBncm91cF9ieShSZWdpb24sWWVhcixHZW5yZSkgJT4lDQogICAgc3VtbWFyaXNlKCJDb3BpZXMgU29sZCIgPSBzdW0oYENvcGllcyBTb2xkYCkpICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHg9WWVhciwNCiAgICAgICAgeT1gQ29waWVzIFNvbGRgLA0KICAgICAgICBmaWxsID0gR2VucmUpICsgDQogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSsNCiAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdD0wLjk1LCB2anVzdD0wLjIpKSArDQogICAgeWxhYigiTnVtYmVyIG9mIENvcGllcyBTb2xkIChpbiBtaWxsaW9ucykiKQ0KICAgIA0KZ2dwbG90bHkoZ3JhcGgxKQ0KYGBgDQoNCmBgYHtyfQ0KI051bWJlciBSZWxlYXNlcw0KZ3JhcGgyIDwtIGdhbWVfbWVsdCAlPiUgDQogICAgZmlsdGVyKFJlZ2lvbiA9PSAiTkFfU2FsZXMiKSAlPiUNCiAgICBncm91cF9ieShSZWdpb24sWWVhcixHZW5yZSkgJT4lDQogICAgY291bnQoWWVhcixHZW5yZSkgJT4lDQogICAgcmVuYW1lKGBOdW1iZXIgb2YgUmVsZWFzZXNgPSJuIiklPiUgDQogICAgZ2dwbG90KCkgKw0KICAgIGFlcyh4PVllYXIsDQogICAgICAgIHk9YE51bWJlciBvZiBSZWxlYXNlc2AsDQogICAgICAgIGZpbGwgPSBHZW5yZSkgKyANCiAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKw0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0PTAuOTUsIHZqdXN0PTAuMikpKw0KICAgIHlsYWIoIk51bWJlciBvZiBHYW1lcyBSZWxlYXNlZCIpDQpnZ3Bsb3RseShncmFwaDIpDQpgYGANCmBgYHtyfQ0KI051bWJlciBvZiBQbGF0Zm9ybXMsIEdlbnJlcyBhbmQgUHVibGlzaGVycyB3aXRoIGdhbWVzID4gMTAwIGNvcGllcyBzb2xkIA0KZ3JhcGgzIDwtIGdhbWVfbWVsdCAlPiUgDQogICAgZmlsdGVyKFJlZ2lvbiA9PSAiSlBfU2FsZXMiKSAlPiUNCiAgICBncm91cF9ieShZZWFyKSU+JQ0KICAgIG1lbHQoaWQudmFycz1jKCJZZWFyIiksbWVhc3VyZS52YXJzPWMoIkdlbnJlIiwiUGxhdGZvcm0iLCJQdWJsaXNoZXIiKSkgJT4lDQogICAgcmVuYW1lKENhdGVnb3J5PSd2YXJpYWJsZScpICU+JSANCiAgICBncm91cF9ieShZZWFyLENhdGVnb3J5KSAlPiUNCiAgICB1bmlxdWUoKSAlPiUNCiAgICBjb3VudChZZWFyLENhdGVnb3J5KSAlPiUNCiAgICByZW5hbWUoYENvdW50cyBvZiBHZW5yZXMsIFB1Ymxpc2hlcnMgYW5kIFBsYXRmb3Jtc2A9IG4pICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHg9WWVhciwNCiAgICAgICAgeT1gQ291bnRzIG9mIEdlbnJlcywgUHVibGlzaGVycyBhbmQgUGxhdGZvcm1zYCwNCiAgICAgICAgZmlsbCA9IENhdGVnb3J5KSArIA0KICAgIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikrDQogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3Q9MC45NSwgdmp1c3Q9MC4yKSkrDQogICAgeWxhYigiQ291bnRzIG9mIEdlbnJlcywgUHVibGlzaGVycyBhbmQgUGxhdGZvcm1zIikNCmdncGxvdGx5KGdyYXBoMykNCmBgYA0KDQpgYGB7cn0NCnRlc3RmeGMgPC1mdW5jdGlvbihyZWcscGxhdCxnZW4scHViLHllYXJzKSB7DQogICAgICAgICAjIElucHV0OiBMaXN0IG9mIFJlZ2lvbnMsIFBsYXRmb3JtcywgR2VucmVzLCBQdWJsaXNoZXJzLCBNaW4gYW5kIE1heCBZZWFyDQogICAgICAgICAjIE91dHB1dDogR3JhcGgNCiAgICAgICAgICMNCiAgICAgICAgICMgQ3JlYXRlIHN1YnNldCBiYXNlZCBvbiBmaWx0ZXJzIA0KICAgICAgICAgIyBQYXNzIHRvIGdyYXBoDQogICAgICAgICAjIE91dHB1dCBncmFwaA0KDQogICAgICAgIGZpbHRlcl9yZWdpb24gPSByZWcNCiAgICAgICAgDQogICAgICAgICBpZiAocGxhdCAhPSAiYWxsIil7DQogICAgICAgICAgICAgZmlsdGVyX3BsYXQgPSBwbGF0DQogICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgIGZpbHRlcl9wbGF0ID0gdW5pcXVlKGdhbWVfbWVsdCRQbGF0Zm9ybSkNCiAgICAgICAgIH0NCiAgICAgICAgIGlmIChnZW4gIT0gImFsbCIpew0KICAgICAgICAgICAgIGZpbHRlcl9nZW4gPSBnZW4NCiAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgZmlsdGVyX2dlbiA9IHVuaXF1ZShnYW1lX21lbHQkR2VucmUpDQogICAgICAgICB9DQogICAgICAgICBpZiAocHViICE9ICJhbGwiKXsNCiAgICAgICAgICAgICBmaWx0ZXJfcHViID0gcHViDQogICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgIGZpbHRlcl9wdWIgPSB1bmlxdWUoZ2FtZV9tZWx0JFB1Ymxpc2hlcikNCiAgICAgICAgIH0NCiAgICAgICAgIG1pbl95ZWFyID0geWVhcnNbMV0NCiAgICAgICAgIG1heF95ZWFyID0geWVhcnNbMl0NCiAgICAgICAgIA0KICAgICAgICAgZ3JhcGgxIDwtIGdhbWVfbWVsdFssMjo4XSAlPiUgDQogICAgICAgICAgICAgc3Vic2V0KFJlZ2lvbiAlaW4lIGZpbHRlcl9yZWdpb24sIFBsYXRmb3JtICVpbiUgZmlsdGVyX3BsYXQsIEdlbnJlICVpbiUgZmlsdGVyX2dlbiwgUHVibGlzaGVyICVpbiUgZmlsdGVyX3B1YiwgWWVhciA+PSBtaW5feWVhciB8IFllYXIgPD0gbWF4X3llYXIpICU+JQ0KICAgICAgICAgICAgIGdyb3VwX2J5KFJlZ2lvbixZZWFyLEdlbnJlKSAlPiUNCiAgICAgICAgICAgICBzdW1tYXJpc2UoIkNvcGllcyBTb2xkIiA9IHN1bShgQ29waWVzIFNvbGRgKSkgJT4lIA0KICAgICAgICAgICAgIGdncGxvdCgpICsNCiAgICAgICAgICAgICBhZXMoeD1ZZWFyLA0KICAgICAgICAgICAgICAgICB5PWBDb3BpZXMgU29sZGAsDQogICAgICAgICAgICAgICAgIGZpbGwgPSBHZW5yZSkgKyANCiAgICAgICAgICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKw0KICAgICAgICAgICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0PTAuOTUsIHZqdXN0PTAuMikpICsNCiAgICAgICAgICAgICB5bGFiKCJOdW1iZXIgb2YgQ29waWVzIFNvbGQgKGluIG1pbGxpb25zKSIpDQogICAgICAgICBnZ3Bsb3RseShncmFwaDEpDQogICAgfQ0KYGBgDQoNCg0KYGBge3J9DQpmaWx0ZXJfcmVnaW9uID0gbGlzdCgiSlBfU2FsZXMiKQ0KZmlsdGVyX3BsYXQgPSB1bmlxdWUoZ2FtZV9tZWx0JFBsYXRmb3JtKQ0KDQpmaWx0ZXJfZ2VuID0gdW5pcXVlKGdhbWVfbWVsdCRHZW5yZSkNCg0KZmlsdGVyX3B1YiA9IHVuaXF1ZShnYW1lX21lbHQkUHVibGlzaGVyKQ0KDQptaW5feWVhciA9IDE5ODANCm1heF95ZWFyID0gMjAxNw0KIGdyYXBoMSA8LSBnYW1lX21lbHQgJT4lIA0KICAgICBzdWJzZXQoUmVnaW9uICVpbiUgZmlsdGVyX3JlZ2lvbiAmIFBsYXRmb3JtICVpbiUgZmlsdGVyX3BsYXQgJiBHZW5yZSAlaW4lIGZpbHRlcl9nZW4gJiBQdWJsaXNoZXIgJWluJSBmaWx0ZXJfcHViICYgWWVhciA+PSBtaW5feWVhciAmIFllYXIgPD0gbWF4X3llYXIpICU+JQ0KICAgICBncm91cF9ieShZZWFyLEdlbnJlKSAlPiUNCiAgICAgc3VtbWFyaXNlKCJDb3BpZXMgU29sZCIgPSBzdW0oYENvcGllcyBTb2xkYCkpICU+JSANCiAgICAgZ2dwbG90KCkgKw0KICAgICBhZXMoeD1ZZWFyLA0KICAgICAgICAgeT1gQ29waWVzIFNvbGRgLA0KICAgICAgICAgZmlsbCA9IEdlbnJlKSArIA0KICAgICBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpKw0KICAgICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdD0wLjk1LCB2anVzdD0wLjIpKSArDQogICAgIHlsYWIoIk51bWJlciBvZiBDb3BpZXMgU29sZCAoaW4gbWlsbGlvbnMpIikNCiBnZ3Bsb3RseShncmFwaDEpDQp9DQpgYGANCmBgYHtyfQ0Kc29ydCh1bmlxdWUoZ2FtZV9tZWx0JFllYXIpKQ0KZmlsdGVyX3JlZ2lvbiA9ICJOQV9TIg0KZmlsdGVyX3BsYXQgPSBsaXN0KCJXaWkiKQ0KZmlsdGVyX2dlbiA9IHVuaXF1ZShnYW1lX21lbHQkR2VucmUpDQpmaWx0ZXJfcHViID0gdW5pcXVlKGdhbWVfbWVsdCRQdWJsaXNoZXIpDQoiR2xvYmFsX1NhbGVzIiAlaW4lIGZpbHRlcl9yZWdpb24NCmdhbWVfbWVsdCRZZWFyID4gMjAwMA0KbWluX3llYXIgPSAxOTkwDQptYXhfeWVhciA9IDIwMTcNCmdhbWVfbWVsdCAlPiUgDQogICAgIHN1YnNldChSZWdpb24gJWluJSBmaWx0ZXJfcmVnaW9uICYgUGxhdGZvcm0gJWluJSBmaWx0ZXJfcGxhdCAmIEdlbnJlICVpbiUgZmlsdGVyX2dlbiAmIFB1Ymxpc2hlciAlaW4lIGZpbHRlcl9wdWIgJiBZZWFyID49IG1pbl95ZWFyICYgWWVhciA8PSBtYXhfeWVhcikNCmBgYA0KDQo=